﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Facebook;
using Facebook.Session;
using Facebook.Rest;
using Facebook.Schema;
using Coot.Properties;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Xml;
using System.Xml.Linq;
using System.Net;

namespace Coot
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        [System.Runtime.InteropServices.DllImport("gdi32")]
        static extern int DeleteObject(IntPtr o);

        DesktopSession session;
        Api api;
        string sessionKey;
        string sessionSecret;
        long uid;
        string name;
        string pic_square;
        GenericPhotoCollection photos;
        bool loggedIn = false;
        FBFriendList friends;
        List<long> selectedUids;
        List<long> taggedUids;

        public MainWindow()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            session.Login();
        }

        void session_LoginCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {
            sessionKey = session.SessionKey;
            sessionSecret = session.SessionSecret;
            uid = session.UserId;
            selectedUids = new List<long>();
            taggedUids = new List<long>();

            Settings.Default.sessionKey = sessionKey;
            Settings.Default.sessionSecret = sessionSecret;
            Settings.Default.uid = uid;
            Settings.Default.selectedUids = new System.Collections.Specialized.StringCollection();
            Settings.Default.taggedUids = new System.Collections.Specialized.StringCollection();
            Settings.Default.Save();

            selectedUids.Add(uid);
            taggedUids.Add(uid);

            getLoginInfo();

            loginButton.Content = "Logout";
            loginButton.IsEnabled = true;
            loggedIn = true;
        }

        private void button2_Click(object sender, RoutedEventArgs e)
        {
            sessionKey = Settings.Default.sessionKey;
            sessionSecret = Settings.Default.sessionSecret;
            //uid = Settings.Default.uid;
            //name = Settings.Default.name;
            //this.Title = name;

            BitmapImage bmp = new BitmapImage();
            bmp.DownloadCompleted += new EventHandler(bmp_DownloadCompleted);
            bmp.BeginInit();
            bmp.UriSource = new Uri(Settings.Default.pic_square);
            bmp.EndInit();

            session = new DesktopSession("490e4f4f0e12c48d96b8794aa3fcd3d1", sessionSecret, sessionKey, true, new List<Enums.ExtendedPermissions>() { Enums.ExtendedPermissions.offline_access });
            session.LoginCompleted += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(session_LoginCompleted);
            api = new Api(session);
        }

        private void button3_Click(object sender, RoutedEventArgs e)
        {
            Dictionary<string, string> queries = new Dictionary<string,string>();

            queries.Add("info", "SELECT uid, name, pic_square FROM user WHERE uid = " + uid.ToString());
            queries.Add("taggedPhotos", "SELECT src_big, caption, src_big_width, src_big_height FROM photo WHERE pid IN (SELECT pid FROM photo_tag WHERE subject = " + uid.ToString() + ") ORDER BY aid ASC");
            queries.Add("ownPhotos", "SELECT src_big, caption, src_big_width, src_big_height FROM photo WHERE aid IN (SELECT aid FROM album WHERE owner = " + uid.ToString() + ") ORDER BY aid ASC");

            IList<fql_result> results = api.Fql.Multiquery(queries);

            name = getXmlValue(results[0].fql_result_set.CreateReader(), "name");
            string pic = getXmlValue(results[0].fql_result_set.CreateReader(), "pic_square");

            Settings.Default.name = name;
            Settings.Default.pic_square = pic;
            Settings.Default.Save();

            this.Title = name;

            BitmapImage bmp = new BitmapImage();
            bmp.DownloadCompleted += new EventHandler(bmp_DownloadCompleted);
            bmp.BeginInit();
            bmp.UriSource = new Uri(pic);
            bmp.EndInit();

            XmlNodeList ownPhotoNodes = getXmlNodes(results[1].fql_result_set.CreateReader(), "photo");
            XmlNodeList taggedPhotoNodes = getXmlNodes(results[2].fql_result_set.CreateReader(), "photo");

            photos = new GenericPhotoCollection();

            foreach (XmlNode node in ownPhotoNodes)
            {
                photos.AddPhoto(node["src_big"].InnerText, node["caption"].InnerText, int.Parse(node["src_big_width"].InnerText), int.Parse(node["src_big_height"].InnerText));
            }
            foreach (XmlNode node in taggedPhotoNodes)
            {
                photos.AddPhoto(node["src_big"].InnerText, node["caption"].InnerText, int.Parse(node["src_big_width"].InnerText), int.Parse(node["src_big_height"].InnerText));
            }
        }

        private void button4_Click(object sender, RoutedEventArgs e)
        {
            session = new DesktopSession("490e4f4f0e12c48d96b8794aa3fcd3d1", true, new List<Enums.ExtendedPermissions>() { Enums.ExtendedPermissions.offline_access });
            session.LoginCompleted += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(session_LoginCompleted);
            api = new Api(session);
        }

        private void button5_Click(object sender, RoutedEventArgs e)
        {
            GenericPhoto photo = photos.GetRandomPhoto();

            this.Title = photo.Caption + " - " + photo.Source;

            BitmapImage bmp = new BitmapImage();
            bmp.DownloadCompleted += new EventHandler(bmp_DownloadCompleted);
            bmp.BeginInit();
            bmp.UriSource = new Uri(photo.Source);
            bmp.EndInit();
            profileImage.Width = photo.Width;
            profileImage.Height = photo.Height;
        }

        void bmp_DownloadCompleted(object sender, EventArgs e)
        {
            BitmapImage bmp2 = (BitmapImage)sender;
            profileImage.Source = bmp2;
        }

        private void button6_Click(object sender, RoutedEventArgs e)
        {
            ScreenSaver screenSaver = new ScreenSaver();
            screenSaver.ShowDialog();

            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();
        }

        private void mainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            System.Net.ServicePointManager.Expect100Continue = false;
            checkBox1.IsChecked = Settings.Default.useTransparency;
            customColorPicker1.SelectedColor = Settings.Default.background;
            slider1.Value = Settings.Default.numberOfPhotos;
            uid = Settings.Default.uid;
            name = Settings.Default.name;
            sessionKey = Settings.Default.sessionKey;
            sessionSecret = Settings.Default.sessionSecret;
            pic_square = Settings.Default.pic_square;

            if (uid != 0 && sessionKey != null && sessionSecret != null) // If a previous session exists
            {
                loginButton.Content = "Logout";
                loggedIn = true;

                session = new DesktopSession("490e4f4f0e12c48d96b8794aa3fcd3d1", sessionSecret, sessionKey, true, new List<Enums.ExtendedPermissions>() { Enums.ExtendedPermissions.offline_access });
                session.LoginCompleted += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(session_LoginCompleted);
                api = new Api(session);

                selectedUids = new List<long>();
                taggedUids = new List<long>();

                if (Settings.Default.selectedUids != null && Settings.Default.taggedUids != null)
                {
                    foreach (string selectedUid in Settings.Default.selectedUids)
                    {
                        selectedUids.Add(long.Parse(selectedUid));
                    }

                    foreach (string taggedUid in Settings.Default.taggedUids)
                    {
                        taggedUids.Add(long.Parse(taggedUid));
                    }
                }

                getLoginInfo();
            }
        }

        private void checkBox1_Checked(object sender, RoutedEventArgs e)
        {
            Settings.Default.useTransparency = true;
            Settings.Default.Save();
        }

        private void checkBox1_Unchecked(object sender, RoutedEventArgs e)
        {
            Settings.Default.useTransparency = false;
            Settings.Default.Save();
        }

        private void slider1_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            if (label2 != null)
            {
                label2.Content = ((int)slider1.Value).ToString();
                Settings.Default.numberOfPhotos = (int)slider1.Value;
                Settings.Default.Save();
            }
        }

        private void customColorPicker1_SelectedColorChanged(System.Windows.Media.Color obj)
        {
            Settings.Default.background = obj;
            Settings.Default.Save();
        }

        private string getXmlValue(string xml, string key)
        {
            XmlDocument xDoc = new XmlDocument();
            xDoc.LoadXml(xml);
            XmlNodeList nodes = xDoc.GetElementsByTagName(key);
            return nodes[0].InnerText;
        }

        private string getXmlValue(XmlReader xml, string key)
        {
            XmlDocument xDoc = new XmlDocument();
            xDoc.Load(xml);
            XmlNodeList nodes = xDoc.GetElementsByTagName(key);
            return nodes[0].InnerText;
        }

        private XmlNodeList getXmlNodes(string xml, string key)
        {
            XmlDocument xDoc = new XmlDocument();
            xDoc.LoadXml(xml);
            return xDoc.GetElementsByTagName(key);
        }

        private XmlNodeList getXmlNodes(XmlReader xml, string key)
        {
            XmlDocument xDoc = new XmlDocument();
            xDoc.Load(xml);
            return xDoc.GetElementsByTagName(key);
        }

        private void loginButton_Click(object sender, RoutedEventArgs e)
        {
            loginButton.IsEnabled = false;

            if (!loggedIn)
            {
                session = new DesktopSession("490e4f4f0e12c48d96b8794aa3fcd3d1", true, new List<Enums.ExtendedPermissions>() { Enums.ExtendedPermissions.offline_access });
                session.LoginCompleted += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(session_LoginCompleted);
                api = new Api(session);

                session.Login();
            }
            else
            {
                session.LogoutCompleted += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(session_LogoutCompleted);
                session.Logout();
            }
        }

        void session_LogoutCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {
            loggedIn = false;

            sessionKey = null;
            sessionSecret = null;
            name = null;
            uid = 0;
            pic_square = null;
            taggedUids = new List<long>();
            selectedUids = new List<long>();

            Settings.Default.sessionKey = sessionKey;
            Settings.Default.sessionSecret = sessionSecret;
            Settings.Default.uid = uid;
            Settings.Default.name = name;
            Settings.Default.pic_square = pic_square;
            Settings.Default.taggedUids = null;
            Settings.Default.selectedUids = null;
            Settings.Default.Save();

            loginDetails.Visibility = System.Windows.Visibility.Hidden;
            friendsStackPanel.Children.Clear();

            loginButton.Content = "Log in to Facebook";
            loginButton.IsEnabled = true;
        }

        public void getLoginInfo()
        {
            Dictionary<string, string> queries = new Dictionary<string, string>();

            queries.Add("info", "SELECT name, pic_square FROM user WHERE uid = " + uid.ToString());
            queries.Add("friends", "SELECT id, name FROM profile WHERE id IN (SELECT uid2 FROM friend WHERE uid1 = " + uid.ToString() + ") ORDER BY name ASC");

            IList<fql_result> results = api.Fql.Multiquery(queries);

            name = getXmlValue(results[1].fql_result_set.CreateReader(), "name");
            pic_square = getXmlValue(results[1].fql_result_set.CreateReader(), "pic_square");

            XmlNodeList friendsXML = getXmlNodes(results[0].fql_result_set.CreateReader(), "profile");

            friends = new FBFriendList(friendsXML);

            List<FriendItem> friendItems = new List<FriendItem>(friends.Count);

            friendItems.Add(new FriendItem(name + " (me)", uid, taggedUids.Contains(uid), selectedUids.Contains(uid)));

            foreach (FBFriend friend in friends)
            {
                friendItems.Add(new FriendItem(friend.Name, friend.Uid, taggedUids.Contains(friend.Uid), selectedUids.Contains(friend.Uid)));
            }

            friendItems[friendItems.Count - 1].Height = 21;

            foreach (FriendItem friendItem in friendItems)
            {
                friendsStackPanel.Children.Add(friendItem);
            }

            Settings.Default.name = name;
            Settings.Default.pic_square = pic_square;
            Settings.Default.Save();

            nameLabel.Content = name;
            BitmapImage bmp = new BitmapImage();
            bmp.DownloadCompleted += new EventHandler(bmp_DownloadCompleted);
            bmp.BeginInit();
            bmp.UriSource = new Uri(pic_square);
            bmp.EndInit();
            loginDetails.Visibility = System.Windows.Visibility.Visible;
        }

        private void okButton_Click(object sender, RoutedEventArgs e)
        {
            this.Close();
        }

        private void mainWindow_Closed(object sender, EventArgs e)
        {
            Settings.Default.selectedUids = new System.Collections.Specialized.StringCollection();
            Settings.Default.taggedUids = new System.Collections.Specialized.StringCollection();
            selectedUids = new List<long>();
            taggedUids = new List<long>();

            foreach (FriendItem friend in friendsStackPanel.Children)
            {
                if (friend.Selected)
                    selectedUids.Add(friend.FriendUid);
                if (friend.TaggedSelected)
                    taggedUids.Add(friend.FriendUid);
            }

            foreach (long selectedUid in selectedUids)
            {
                Settings.Default.selectedUids.Add(selectedUid.ToString());
            }

            foreach (long taggedUid in taggedUids)
            {
                Settings.Default.taggedUids.Add(taggedUid.ToString());
            }

            Settings.Default.lastUpdate = new DateTime(1);

            Settings.Default.Save();
        }

        private void allAlbums_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            foreach (FriendItem friend in friendsStackPanel.Children)
            {
                friend.Selected = true;
            }
        }

        private void noAlbums_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            foreach (FriendItem friend in friendsStackPanel.Children)
            {
                friend.Selected = false;
            }
        }

        private void allTagged_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            foreach (FriendItem friend in friendsStackPanel.Children)
            {
                friend.TaggedSelected = true;
            }
        }

        private void noTagged_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            foreach (FriendItem friend in friendsStackPanel.Children)
            {
                friend.TaggedSelected = false;
            }
        }
    }
}
